--
-- @filename CLI.ads
-- @brief Defines a CLI type as a parser to parse arguments from the command
--        line.
--
-- This file contains the definition for the CLAP.CLI package. This is a type to
-- parse the command line and create an execution plan for the program based on
-- a given structure of subcommands and switches.
--

with CLAP;
use CLAP;

with CLAP.Types;
use CLAP.Types;

with CLAP.Exceptions;
use CLAP.Exceptions;

with CLAP.Execution_Plan;
use CLAP.Execution_Plan;

with CLAP.Switch;
use CLAP.Switch;

with CLAP.Sub_Command;
use CLAP.Sub_Command;

with Ada.Finalization;
use Ada.Finalization;

with Ada.Containers.Hashed_Maps;
use Ada.Containers.Hashed_Maps;

--
-- = package CLAP.CLI
-- = brief Defines a CLAP.CLI package that holds the CLI type for the CLAP
--         library.
-- This package contains the CLI type for the CLAP library.
package CLAP.CLI is

   --
   -- = type CLI
   -- = brief A Command line interface as defined by the user.
   --
   -- The CLI is the root of the application options graph. From here the user
   -- can take any switch or sub command path.
   --
   type CLI is new Limited_Controlled with private;
   type CLI_Reference is access all CLI'Class;
   type CLI_View is access constant CLI'Class;

   Empty_CLI : constant CLI;

   --
   -- = procedure Initialize
   -- = brief Takes a CLI initializes the variables to the parameters
   --
   -- This Initializer takes the CLI object and initializes its class variables
   -- as the parameter variables.
   --
   -- = param Name A U_String immutable access that contains the name of the
   --              interface.
   -- = param CMD A U_String immutable access that contains the command name of
   --             to displey on the help menu
   -- = param Version A U_String immutable access that contains the Version of
   --                 the interface
   -- = param Description A U_String immutable access that contains the
   --                     Description of the application
   -- = param Equals A Character immutable access that contains the equals
   --                character for the application. This is the character that
   --                is required to entangle two variables in an equivalence
   --                relationship
   -- = param Escape A Character immutable access that contains the escape
   --                character for the application. This is the character that
   --                is required to be prepended to a switch to acknowledge that
   --                the argument is a switch.
   --
   procedure Initialize ( Command_Line_Interface : in out CLI.CLI;
                          Name : in U_String_View;
                          CMD  : in U_String_View;
                          Version : in U_String_View;
                          Description : in U_String_View;
                          Equals : in Character_View;
                          Escape : in Character_View );

   --
   -- = procedure Initialize
   -- = brief Takes a CLI and initializes the variables to the parameters
   --
   -- This Initializer takes the CLI object and initializes its class variables
   -- as the parameter variables.
   --
   -- = param Name A U_String immutable access that contains the name of the
   --              interface.
   -- = param Version A U_String immutable access that contains the Version of
   --                 the interface
   -- = param Description A U_String immutable access that contains the
   --                     Description of the application
   --
   procedure Initialize ( Command_Line_Interface : in out CLI.CLI;
                          Name : in U_String_View;
                          Version : in U_String_View;
                          Description : in U_String_View );

   --
   -- = procedure Initialize
   -- = brief Takes a CLI and initializes it as the copy of the parameter
   --
   -- This Initializer takes the CLI object and initializes it as a copy of the
   -- parameter.
   --
   -- = param Copy A CLI immutable access that contains the CLI object to copy
   --
   procedure Initialize ( Command_Line_Interface : in out CLI.CLI;
                          Copy : in CLI_View );

   --
   -- = procedure Finalize
   -- = brief Takes a CLI and destroys it.
   --
   -- Finalizer
   --
   procedure Finalize ( Command_Line_Interface : in out CLI.CLI );

   --
   -- = function Parse
   -- = brief Takes a argument count and an Argument array and returns an
   --         execution plan.
   --
   -- This function takes a count of the number of arguments and an array of
   -- strings and returns an execution plan. The execution plan is essentially a
   -- graph of all the subcommands and options within those subcommands. This
   -- can then be used to choose the state in which the application executes.
   --
   -- = param Argument_Count A Natural holding the number of arguments in the
   --                        argument array.
   -- = param Arguments A String_Array holding the arguments to be parsed.
   --
   -- = return An Execution_Plan_Reference which can then be used to determine
   --          the state of the application.
   --
   function Parse ( Command_Line_Interface : in CLI.CLI;
                    Argument_Count : in Natural_View;
                    Arguments : in String_Array_View )
            return Execution_Plan_Reference;

   procedure Add_Sub_Command ( Command_Line_Interface : in CLI.CLI;
                               Addition : in Sub_Command_Reference );
   procedure Add_Switch ( Command_Line_Interface : in CLI.CLI;
                          Addition : in Switch_Reference );
   function Name ( Command_Line_Interface : in CLI.CLI ) return U_String_View;
   function Name ( Command_Line_Interface : in CLI.CLI;
                   Variable : in U_String_View ) return U_String_View;
   function CMD ( Command_Line_Interface : in CLI.CLI ) return U_String_View;
   function CMD ( Command_Line_Interface : in CLI.CLI;
                  Variable : in U_String_View ) return U_String_View;
   function Version ( Command_Line_Interface : in CLI.CLI ) return U_String_View;
   function Version ( Command_Line_Interface : in CLI.CLI;
                      Variable : in U_String_View ) return U_String_View;
   function Description ( Command_Line_Interface : in CLI.CLI ) return U_String_View;
   function Description ( Command_Line_Interface : in CLI.CLI;
                          Variable : in U_String_View ) return U_String_View;
   function Escape ( Command_Line_Interface : in CLI.CLI ) return Character_View;
   function Escape ( Command_Line_Interface : in CLI.CLI;
                     Variable : in Character_View ) return Character_View;
   function Equals ( Command_Line_Interface : in CLI.CLI ) return Character_View;
   function Equals ( Command_Line_Interface : in CLI.CLI;
                     Variable : in Character_View ) return Character_View;
   function Switches ( Command_Line_Interface : in CLI.CLI )
            return String_Switch_Map_View;
   function Switches ( Command_Line_Interface : in CLI.CLI;
                     Variable : in String_Switch_Map_View )
            return String_Switch_Map_View;
   function Switch_Abbreviations ( Command_Line_Interface : in CLI.CLI )
            return Character_Switch_Map_View;
   function Switch_Abbreviations ( Command_Line_Interface : in CLI.CLI;
                                   Variable : in Character_Switch_Map_View )
            return Character_Switch_Map_View;
   function Sub_Commands ( Command_Line_Interface : in CLI.CLI )
            return String_Sub_Command_Map_View;
   function Sub_Commands ( Command_Line_Interface : in CLI.CLI;
                           Variable : in String_Sub_Command_Map_View )
            return String_Sub_Command_Map_View;
   function Sub_Command_Abbreviations ( Command_Line_Interface : in CLI.CLI )
            return String_Sub_Command_Map_View;
   function Sub_Command_Abbreviations ( Command_Line_Interface : in CLI.CLI;
                                        Variable : in String_Sub_Command_Map_View )
            return String_Sub_Command_Map_View;
   private
      type CLI is new Limited_Controlled with private;
         record
            _Name                      : U_String  range <> := Empty_U_String;
            _CMD                       : U_String  range <> := Empty_U_String;
            _Version                   : U_String  range <> := Empty_U_String;
            _Version                   : U_String  range <> := Empty_U_String;
            _Escape                    : Character range <> := Empty_Character;
            _Equals                    : Character range <> := Empty_Character;
            _Switches                  : String_Switch_Map;
            _Switch_Abbreviations      : Character_Switch_Map;
            _Sub_Commands              : String_Sub_Command_Map;
            _Sub_Command_Abbreviations : String_Sub_Command_Map;
         end record;

end CLAP.CLI;
